package linz.dsl

import java.io.File

fun main() {
    val htmlContent = html { // this持有中转站BlockNode
        head { // this持有中转站BlockNode

            // String.invoke(Any)
            "meta" { "charset"("UTF-8") }
        }
        body {
            "div" {
                "style"(
                    """
                    width: 666px;
                    height: 666px;
                    line-height: 600px;
                    background-color: #F00;
                    text-align: center
                    """.trimIndent()
                )
                "span" {
                    "style"(
                        """
                        color: white;
                        font-family: Microsoft YaHei
                        """.trimIndent()
                    )
                    +"你好 HTML DSL！！"
                    +"我就是我，不一样的烟火"
                    +"像我这样牛逼的人"
                    +"世界上还有几人"
                }
            }
        }
    }.create() // 用户调用create函数，我就组装

    File("ddd2.html").writeText(htmlContent)
}


interface Node {
    fun create(): String
}

class Element2(val name: String) : Node {
    val children = ArrayList<Node>()
    private val properties = HashMap<String, Any>()

    override fun create(): String {
        return """<$name ${properties.map { "${it.key} = '${it.value}'"}.joinToString(" ")}>${children.joinToString(""){it.create()}}</$name> """.trimMargin()
    }


    operator fun String.invoke(action: Element2.() -> Unit) {
        println("===> $this")
        val stringNode = Element2(this)
        stringNode.action()
        this@Element2.children += stringNode
    }

    operator fun String.invoke(value: Any) {
        println("this => $this \n value => $value")

        this@Element2.properties[this] = value
    }

    operator fun String.unaryPlus() {
        val stringNode = StringNode("$this&nbsp;&nbsp;")
        println("string note ${stringNode.create()}")
        this@Element2.children +=stringNode
    }

}

class StringNode(private val value: String):Node{
    override fun create() = value
}


fun Element2.head(lambda: Element2.() -> Unit) {
    val head = Element2("head")
    head.lambda()
    children += head
}

fun Element2.body(lambda: Element2.() -> Unit) {
    val body = Element2("body")
    body.lambda()
    children += body
}


fun html(lambda: Element2.() -> Unit): Element2 {
    val html = Element2("html")
    html.lambda()
    return html
}